/* ************************************************************************
> File Name:     7.c
> Author:        zhfu
> mail:          3346897597@qq.com
> Created Time:  2022年05月05日 星期四 15时09分24秒
> Description:   
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include "stringhash.h"
#define N 20 /*单词的最大长度*/
#define M 20 /*相同长度的单词种类*/

typedef struct{
    char *s;
    unsigned len;
    unsigned cnt;
} word;

my_hash **read_file(my_hash *arr[], FILE *f);
void get_ret(my_hash *arr[], word **ret);
void print_ret(word *ret);
void free_all(my_hash *arr[], word *ret);
int get_word_size(char *s);
int func(char *x);
void swap_word(word *w1, word *w2);

int main(int agrc, char *agrv[])
{
    char *file = agrv[1];
    FILE *f;

    if (!(f = fopen(file, "r"))){
        perror(file);
        exit(1);
    }

    my_hash **arr;
    word *ret;

    arr = read_file(arr, f);
    get_ret(arr, &ret);
    print_ret(ret);
    free_all(arr, ret);

    fclose(f);

    return 0;
}

my_hash **read_file(my_hash *arr[], FILE *f)
{
    arr = malloc(N * sizeof arr[0]);

    int i;
    for (i = 0; i < N; ++i){
        arr[i] = NULL;
    }

    char s[N];
    while (fscanf(f, "%s", s) != EOF){
        int k = get_word_size(s) - 1;
        if (!arr[k]){
            arr[k] = malloc(sizeof (my_hash));
            arr[k]->p = NULL;
            arr[k]->len = M;
            arr[k]->my_hashfunc = func;
            arr[k]->hash_value = NULL;
            arr[k]->i = 0;
            insert(arr[k], s);
        }
        else{
            insert(arr[k], s);
        }
    }
    return arr;
}

int func(char *x)
{
    int ret = 0;
    char *p = x;
    while (*p){
        ret += *p;
        ++p;
    }
    return ret;
}

int get_word_size(char *s)
{
    int i = 0;
    while (*s){
        ++i;
        ++s;
    }

    return i;
}

void get_ret(my_hash *arr[], word **ret)
{
    *ret = calloc(M * N, sizeof(word));

    int i = 0, j = 0, k = 0;
    my_hash *tmp1;
    while (tmp1 = arr[i]){
        j = 0;
        stringlist tmp2 = {(tmp1->p)[j]};
        while (tmp2.head){
            (*ret)[k].s = tmp2.head->item;
            (*ret)[k].len = i + 1;
            (*ret)[k].cnt = get_list_size(&tmp2);
            if (k){
                int index;
                for (index = 0; index < k; ++index){
                    if ((*ret)[k].cnt < (*ret)[index].cnt){
                        word tmp = (*ret)[k];
                        int t;
                        for (t = k; t > index; --t){
                            swap_word(&(*ret)[t], &(*ret)[t-1]);
                        }
                        (*ret)[index] = tmp;
                        break;
                    }
                }
            }
            ++k;
            ++j;
            tmp2.head = (tmp1->p)[j];
        }
        ++i;
    }
}

void swap_word(word *w1, word *w2)
{
    word tmp;
    tmp = *w1;
    *w1 = *w2;
    *w2 = tmp;
}

void print_ret(word *ret)
{
    while (ret->s){
        printf("word:%-20stimes:%d\n", ret->s, ret->cnt);
        ++ret;
    }
}

void free_all(my_hash *arr[], word *ret)
{
    int i;
    for (i = 0; i < M; ++i){
        free_hash(arr[i]);
    }

    free(arr);
    free(ret);
}
